package org.testile.datasetgenerifier;

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.XmlDataSet;
import org.dbunit.dataset.xml.XmlDataSetWriter;

/**
 * Goal that uses a {@link GenericDataSetFactory} to create an instance of
 * {@link GenerifiedDataSet} from an <code>XmlDataSet</code> input file
 * and a generfication script.
 *
 * @goal generify
 * @requiresProject false
 */
public class GenerifierMojo extends AbstractMojo {

	/**
	 * @parameter
	 *			expression="${testile.generify.script}"
	 */
	private String script;
	/**
	 * @parameter
	 */
	private String factoryConfiguration;
	/**
	 * @parameter
	 *			default-value="target/dbunit/export.xml"
	 */
	private String input;
	/**
	 * @parameter
	 *			default-value"target/dbunit/generified-export.xml"
	 */
	private String output;

	@Override
	public void execute() throws MojoExecutionException {
		getLog().info("data-modifier -> Start processing.");

		File inputFile  = new File(input);
		File scriptFile = new File(script);
		File outputFile = getOutputFile();
		GenerifiedDataSet generifiedDataSet = createDataSet(createFactory(), inputFile, scriptFile);
		writeDataSet(generifiedDataSet, outputFile);
		
		getLog().info("data-modifier -> End processing.");
	}

	private GenericDataSetFactory createFactory() {
		if (factoryConfiguration == null) {
			return GenericDataSetFactory.newInstance();
		} else {
			return GenericDataSetFactory.newInstance(factoryConfiguration);
		}
	}

	private GenerifiedDataSet createDataSet(GenericDataSetFactory factory, File inputFile, File script) {
		try {
			return factory.dataSetFrom(new XmlDataSet(new FileInputStream(inputFile)), script);
		} catch (DataSetException ex) {
			throw new IllegalArgumentException("Could not create generified dataset.", ex);
		} catch (FileNotFoundException ex) {
			throw new IllegalArgumentException("Could not create generified dataset.", ex);
		}
	}

	private void writeDataSet(IDataSet dataSet, File output) {
		try {
			XmlDataSetWriter writer = new XmlDataSetWriter(new FileWriter(output), "UTF-8");
			writer.write(dataSet);
		} catch (DataSetException ex) {
			throw new IllegalStateException("Could not write generified dataset to output.", ex);
		} catch (IOException ex) {
			throw new IllegalStateException("Could not write generified dataset to output.", ex);
		}
	}

	private File getOutputFile() {
		return (output == null) ? generifiedFile(new File(input)) : new File(output);
	}

	private File generifiedFile(File file) {
		File parent = file.getParentFile();
		String name = file.getName();

		return new File(parent, "generified-" + name);
	}
}
